"use strict";

import {
  app,
  protocol,
  nativeImage,
  dialog,
  BrowserWindow,
  screen,
  ipcMain
} from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { exec } from "child_process";
import { initExtra, createTray } from "@/utils/backgroundExtra";
import { autoUpdater } from "electron-updater";
import pkg from "../package.json";
import { userInfo } from "os";
var crypto = require("crypto");
var fs = require("fs");
//窗口宽度
var window_width=450;

const isDevelopment = process.env.NODE_ENV !== "production";

let win;
let bounds;
let size;

if (app.requestSingleInstanceLock()) {
  app.on("second-instance", () => {
    if (win) {
      setPosition();
    }
  });
} else {
  app.quit();
}

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: "app", privileges: { secure: true, standard: true } }
]);

async function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({
    width: window_width,
    height: 505,
    minWidth: 446,
    minHeight: 354,
    type: "toolbar",
    frame: false,
    title: pkg.name,
    minimizable: false,
    maximizable: false,
    skipTaskbar: true,
    transparent: true,
    alwaysOnTop: true,
    useContentSize: true,
    webPreferences: {
      webSecurity: false,
      enableRemoteModule: true,
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  setPosition();
  bounds = win.getBounds();
  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
    if (!process.env.IS_TEST) win.webContents.openDevTools();
  } else {
    createProtocol("app");
    // Load the index.html when not in development
    win.loadURL("app://./index.html");
    autoUpdater.checkForUpdatesAndNotify();
  }
  // win.once("ready-to-show", () => {
  //   win.show();
  // });

  //屏蔽windows原生右键菜单
  if (process.platform === "win32") {
    //int WM_INITMENU = 0x116;
    //当一个下拉菜单或子菜单将要被激活时发送此消息，它允许程序在它显示前更改菜单，而不要改变全部
    win.hookWindowMessage(278, function() {
      win.setEnabled(false); //窗口禁用

      setTimeout(() => {
        win.setEnabled(true); //窗口启用
      }, 100); //延时太快会立刻启用，太慢会妨碍窗口其他操作，可自行测试最佳时间

      return true;
    });
  }

  win.on("closed", () => {
    win = null;
  });
}

//闪烁问题
app.commandLine.appendSwitch("wm-window-animations-disabled");

// Quit when all windows are closed.
app.on("window-all-closed", () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) init();
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", async () => {
  size = screen.getPrimaryDisplay().workAreaSize;
  init();
});

app.whenReady().then(() => {
  //register file protocol
  protocol.registerFileProtocol("file", async (request, callback) => {
    //remove file:// part,get real url
    let realurl = decodeURI(request.url.substr(8));
    //使用callback获取真正指向内容
    callback({ filepath: realurl });
  });
});

function init() {
  setTimeout(() => {
    createWindow();
  }, 3000); //延时2s 更短也许也能行，具体看硬件
  initExtra();
  createTray(showWindow);
}

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === "win32") {
    process.on("message", data => {
      if (data === "graceful-exit") {
        app.quit();
      }
    });
  } else {
    process.on("SIGTERM", () => {
      app.quit();
    });
  }
}

function setPosition() {
  const size = screen.getPrimaryDisplay().workAreaSize;
  const winSize = win.getSize();
  win.setPosition(size.width - winSize[0] + 20, 30);
}

function showWindow() {
  if (!win.isVisible()) win.show();
}

//设置壁纸,目前只支持meta ，传如图片url
async function setWallPaperViaUrl(url) {
  var pathWay = "/home/" + userInfo().username + "/Pictures/";
  var md5 = crypto.createHash("md5");
  var hashName = md5.update(url).digest("hex");
  //检查文件是否存在
  let exists = fs.existsSync(pathWay + hashName + ".jpg");
  if (!exists) {
    exec(
      `eval wget ${url} -O /home/$USER/Pictures/${hashName}.jpg&&dconf write /org/mate/desktop/background/picture-filename "'/home/$USER/Pictures/${hashName}.jpg'"`,
      () => {
        // if (error != null) {
        //   dialog.showMessageBox({
        //     message: "定时更换壁纸错误",
        //     detail: "请检查网络，并移除可能失效的壁纸\n" + stderr
        //   });
        // }
      }
    );
  } else {
    exec(
      `dconf write /org/mate/desktop/background/picture-filename "'/home/$USER/Pictures/${hashName}.jpg'"`,
      // (error, stdout, stderr) => {
      //   if (error != null) {
      //     dialog.showMessageBox({
      //       message: "定时更换壁纸错误",
      //       detail: "文件不存在\n" + stderr
      //     });}}
      () => {}
    );
  }
}

//设置壁纸,目前只支持meta ，传如图片url,不提示弹窗
async function setWallPaperViaUrlSilently(url) {
  var md5 = crypto.createHash("md5");
  var hashName = md5.update(url).digest("hex");
  console.log("文件名md5" + hashName);
  var pathWay = "/home/" + userInfo().username + "/Pictures/favo/";

  //检查文件夹是否存在
  let exists = fs.existsSync(pathWay);
  if (!exists) {
    exec(`eval mkdir /home/$USER/Pictures/favo/`, (error, stdout, stderr) => {
      if (error != null) {
        dialog.showMessageBox({
          message: "创建文件夹错误",
          detail: "创建文件夹错误\n" + stderr
        });
      }
    });
  }
  //检查文件是否存在
  exists = fs.existsSync(pathWay + hashName + ".jpg");
  //这里有bug 暂时先每次都重新下载
  if (!exists) {
    exec(
      `eval wget ${url} -O /home/$USER/Pictures/favo/${hashName}.jpg&&dconf write /org/mate/desktop/background/picture-filename "'/home/$USER/Pictures/favo/${hashName}.jpg'"`,
      (error, stdout, stderr) => {
        if (error != null) {
          dialog.showMessageBox({
            message: "定时更换壁纸错误",
            detail: "请检查网络，并移除可能失效的壁纸\n" + stderr
          });
        }
      }
    );
  } else {
    exec(
      `dconf write /org/mate/desktop/background/picture-filename "'/home/$USER/Pictures/favo/${hashName}.jpg'"`,
      (error, stderr) => {
        if (error != null) {
          dialog.showMessageBox({
            message: "定时更换壁纸错误",
            detail: "文件不存在\n" + stderr
          });
        }
      }
    );
  }
}

ipcMain.handle("hideWindow", () => {
  win.hide();
});

//ipc主进程处理函数
ipcMain.handle("setWallPaperViaUrl", (event, url) => setWallPaperViaUrl(url));
ipcMain.handle("setWallPaperViaUrlSilently", (event, url) =>
  setWallPaperViaUrlSilently(url)
);
//鼠标移入时，将窗口归位
ipcMain.handle("winShow", () => {
  if (size.width - bounds.x - bounds.width > 20) return;
  win.setBounds({ width: bounds.width, x: size.width + 15 - bounds.width });
});
//鼠标移出时窗口归位，要保证归位窗口起始位置必须贴边显示，否则
ipcMain.handle("winHide", () => {
  bounds = win.getBounds();
  //移出后首先保存位置，然后移动窗口
  if (size.width - bounds.x - bounds.width > 20) return;
  win.setBounds({ x: size.width - 15 });
});
ipcMain.handle("isMoveNeed", () => {
  let position = win.getBounds();
  let screenssize = screen.getPrimaryDisplay().workAreaSize;
  console.log(screenssize.width - position.x - position.width);
  //if (screenssize.width-position.x-position.width>=0) dialog.showMessageBox({message:"将窗口向右移动后会自动贴边哦！"})
});

//窗口大小切换为最大长度
ipcMain.handle("switchWindowSize", () => {
  console.log(win.getSize());
  if (win.getSize()[1] != 505) {
    win.setSize(window_width, 505);
  } else {
    win.setSize(window_width, screen.getPrimaryDisplay().workAreaSize.height);
  }
});

ipcMain.on("ondragstart", (event, icon) => {
  try {
    event.sender.startDrag({
      file: icon.path,
      icon: nativeImage.createFromPath(icon.src.slice(7)).resize({ width: 50 })
    });
  } catch (e) {
    console.log(e);
  }
});
const USER_HOME = process.env.HOME || process.env.USERPROFILE;
ipcMain.handle("userhome", () => {
  return USER_HOME;
});
// 添加窗口发来的信息：打开文件夹去选择音乐
ipcMain.on("open-music-file", event => {
  dialog
    .showOpenDialog({
      properties: ["openFile", "multiSelections"],
      filters: [{ name: "Music", extensions: ["mp3", "flac"] }]
    })
    .then(res => {
      // 拿到结果
      const { canceled, filePaths } = res;
      if (!canceled && filePaths.length) {
        event.sender.send("selected-file", filePaths);
      }
    })
    .catch(() => {});
});
